home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / FPSE_src / dis.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  11KB  |  408 lines

  1. /*
  2.     MIPS disassembler
  3.     =================
  4.  
  5.     Written by BERO
  6. */
  7.  
  8. #include "fpse.h"
  9.  
  10. static char *regname[32] = {
  11.      "zero","at","v0","v1","a0","a1","a2","a3",
  12.      "t0","t1","t2","t3","t4","t5","t6","t7",
  13.      "s0","s1","s2","s3","s4","s5","s6","s7",
  14.      "t8","t9","k0","k1","gp","sp","fp","ra"
  15. };
  16.  
  17. static char *cop0regname[32] = {
  18.      /* from mips 4400 manual
  19.     "Index","Random","EntryLo0","EntryLo1","Context","PageMask","Wired","$7",
  20.     "BadVAddr","Count","EntryHi","Compare","Status","Cause","EPC","PRId",
  21.     "Config","LLAddr","WatchLo","WatchHi","XContext","$21","$22","$23",
  22.     "$24","$25","ECC","CacheErr","TagLo","TagHi","ErrorEPC","$31"
  23.      */
  24.     "INDEX","RAND","TLBL","BPC","CTXT","BDA","TAR","DCIC",
  25.     "BADV","BDAM","TLBH","BPCM","SR","CAUSE","EPC","PRID",
  26.     "ERREG","$17","$18","$19","$20","$21","$22","$23",
  27.     "$24","$25","$26","$27","$28","$29","$30","$31"
  28. };
  29.  
  30. static char *cop2cregname[32] = {
  31.      "R11R12","R13R21","R22R23","R31R32","R33","TRX","TRY","TRZ",
  32.      "L11L12","L13L21","L22L23","L31L32","L33","RBK","GBK","BBK",
  33.      "LR1LR2","LR3LG1","LG2LG3","LB1LB2","LB3","RFC","GFC","BFC",
  34.      "OFX","OFY","H","DQA","DQB","ZSF3","ZSF4","FLAG"
  35. };
  36.  
  37. static char *cop2regname[32] = {
  38.      "VXY0","VZ0","VXY1","VZ1","VXY2","VZ2","RGB","OTZ",
  39.      "IR0","IR1","IR2","IR3","SXY0","SXY1","SXY2","SXYP",
  40.      "SZ0","SZ1","SZ2","SZ3","RGB0","RGB1","RGB2","RES1",
  41.      "MAC0","MAC1","MAC2","MAC3","IRGB","ORGB","LZCS","LZCR"
  42. };
  43.  
  44. static char *cregname[32] = {
  45.      "$0","$1","$2","$3","$4","$5","$6","$7",
  46.      "$8","$9","$10","$11","$12","$13","$14","$15",
  47.      "$16","$17","$18","$19","$20","$21","$22","$23",
  48.      "$24","$25","$26","$27","$28","$29","$30","$31"
  49. };
  50.  
  51. static char *nemonic[64] = {
  52.      "special","bcond","j","jal","beq","bne","blez","bgtz",
  53.      "addi","addiu","slti","sltiu","andi","ori","xori","lui",
  54.      "cop0","cop1","cop2","cop3","","","","",
  55.      "","","","","","","","",
  56.      "lb","lh","lwl","lw","lbu","lhu","lwr","",
  57.      "sb","sh","swl","sw","","","swr","",
  58.      "lwc0","lwc1","lwc2","lwc3","","","","",
  59.      "swc0","swc1","swc2","swc3","","","",""
  60. };
  61.  
  62. static char *special[64] = {
  63.      "sll","","srl","sra","sllv","","srlv","srav",
  64.      "jr","jalr","","","syscall","break","","",
  65.      "mfhi","mthi","mflo","mtlo","","","","",
  66.      "mult","multu","div","divu","","","","",
  67.      "add","addu","sub","subu","and","or","xor","nor",
  68.      "","","slt","sltu","","","","",
  69.      "","","","","","","","",
  70.      "","","","","","","",""
  71. };
  72.  
  73. static char *bcond[32] = {
  74.      "bltz","bgez","","","","","","",
  75.      "","","","","","","","",
  76.      "bltzal","bgezal","","","","","","",
  77.      "","","","","","","",""
  78. };
  79.  
  80. static char *cop[16] = {
  81.      "mfc","","cfc","","mtc","","ctc","",
  82.      "bc","","","","bc","","",""
  83. };
  84.  
  85. static char *cop0[32] = {
  86.      "","tlbr","tlbwi","","","","tlbwr","",
  87.      "tlbp","","","","","","","",
  88.      "rfe","","","","","","","",
  89.      "","","","","","","",""
  90. };
  91.  
  92. #define   MASK(from,n)   (((1<<(n))-1)<<(from))
  93. #define   CHECK(a)
  94.  
  95. #define rdna regname[rdno]
  96. #define rtna regname[rtno]
  97. #define rsna regname[rsno]
  98.  
  99. int dumpreg = 1;
  100. int rlist[4] = { 0,0,0,0 };
  101.  
  102. #ifndef MAKEDIS
  103. void watch(int num)
  104. {
  105.     int i;
  106.  
  107.     if (num < 0) {
  108.         for(i=0;i<32;i++) 
  109.             printf("%-4s = %08x ",regname[i],(int)reg.r[i]);
  110.         printf("\n");
  111.     } else printf("%-4s = %08x\n",regname[num],(int)reg.r[num]);
  112. }
  113.  
  114. void watchcop(int num)
  115. {
  116.     int i;
  117.  
  118.     switch (num) {
  119.     case 2:
  120.         for(i=0;i<32;i++) 
  121.             printf("%-4s = %08x ",cop2cregname[i],(int)reg.ccr2[i]);
  122.         break;
  123.     case 3:
  124.         for(i=0;i<32;i++) 
  125.             printf("%-4s = %08x ",cop2regname[i],(int)reg.cpr2[i]);
  126.         break;
  127.     }
  128.     printf("\n");
  129. }
  130.  
  131. static int reduce(int n)
  132. {
  133.  int x,y;
  134.  
  135.  for (x=0;x<n;)
  136.     {
  137.         if (rlist[x]==0 || rlist[x+1]==rlist[x]) {
  138.             for (y=x;y<n;y++) rlist[y] = rlist[y+1];
  139.             n--;
  140.         } else x++;
  141.     }
  142.  return n;
  143. }
  144. #endif
  145.  
  146. #ifdef MAKEDIS
  147. #define DUMPREG(r1,r2,r3)
  148. #else
  149. #define DUMPREG(r1,r2,r3)   if (dumpreg) {                           \
  150.                                 int nreg;                            \
  151.                                 rlist[0] = r1;                       \
  152.                                 rlist[1] = r2;                       \
  153.                                 rlist[2] = r3;                       \
  154.                                 nreg = reduce(3);                    \
  155.                                 while (nreg--)                       \
  156.                                     sprintf(buf,"%s %s=%08x",buf,    \
  157.                                             regname[rlist[nreg]],    \
  158.                                        (int)reg.r[rlist[nreg]]);     \
  159.                             }
  160. #endif
  161.  
  162. void disasm(char *buf, UINT32 code, UINT32 addr)
  163. {
  164.     int op,func; // ,rs,rt,rd,immS;
  165.  
  166.     if (!code) {
  167.         strcpy(buf,"nop");
  168.         return;
  169.     }
  170.  
  171.     op = code>>26;
  172. /*    rs = (code>>21)&31;
  173.     rt = (code>>16)&31;
  174.     rd = (code>>11)&31;
  175.     immS = (short)code;
  176. */
  177.     switch(op){
  178.     case SPECIAL:
  179.         func = code&63;
  180.         switch(func){
  181.         case SLL:
  182.         case SRL:
  183.         case SRA:
  184.             CHECK(rsno) /* err */
  185.             sprintf(buf,"%-5s %s,%s,%d\t",
  186.                     special[func],rdna,rtna,(int)((code>>6)&31));
  187.             DUMPREG(rdno,rtno,0)
  188.             break;
  189.         case SLLV:
  190.         case SRLV:
  191.         case SRAV:
  192.             CHECK(code & MASK(6,5)) /* err */
  193.             sprintf(buf,"%-5s %s,%s,%s\t",special[func],rdna,rtna,rsna);
  194.             DUMPREG(rdno,rtno,rsno)
  195.             break;
  196.         case JR:
  197.             CHECK(code & MASK(6,15)) /* err */
  198.             sprintf(buf,"%-5s %s\t\t",special[func],rsna);
  199.             DUMPREG(rsno,0,0)
  200.             break;
  201.         case JALR:
  202.             CHECK(code & (MASK(6,5)|MASK(16,5))) /* err */
  203.             sprintf(buf,"%-5s %s,%s\t",special[func],rsna,rdna);
  204.             DUMPREG(rdno,rsno,0)
  205.             break;
  206.         case SYSCALL:
  207.         case BREAK:
  208.             sprintf(buf,"%-5s %08x",special[func],(int)((code>>6)&0xfffff));
  209.             break;
  210.         case MFHI:
  211.         case MFLO:
  212.             CHECK(code & (MASK(6,5)|MASK(16,10))) /* err */
  213.             sprintf(buf,"%-5s %s\t",special[func],rdna);
  214.             DUMPREG(rdno,0,0)
  215.             break;
  216.         case MTHI:
  217.         case MTLO:
  218.             CHECK(code & MASK(6,15)) /* err */
  219.             sprintf(buf,"%-5s %s\t",special[func],rsna);
  220.             DUMPREG(rsno,0,0)
  221.             break;
  222.         case MULT:
  223.         case MULTU:
  224.         case DIV:
  225.         case DIVU:
  226.             CHECK(code & MASK(6,10)) /* error */
  227.             sprintf(buf,"%-5s %s,%s\t",special[func],rsna,rtna);
  228.             DUMPREG(rsno,rtno,0)
  229.             break;
  230.         case ADD:
  231.         case ADDU:
  232.         case SUB:
  233.         case SUBU:
  234.         case AND:
  235.         case OR:
  236.         case XOR:
  237.         case NOR:
  238.         case SLT:
  239.         case SLTU:
  240.             CHECK(code & MASK(6,5)) /* err */
  241.             sprintf(buf,"%-5s %s,%s,%s\t",special[func],rdna,rsna,rtna);
  242.             DUMPREG(rdno,rtno,rsno)
  243.             break;
  244.         default:
  245.             strcpy(buf,"unknown special");
  246.             break;
  247.         }
  248.         break;
  249.     case BCOND:
  250.         sprintf(buf,"%-5s %s,%08x\t",bcond[rtno],rsna,(int)(addr+(immS+1)*4));
  251.         DUMPREG(rsno,0,0)
  252.         break;
  253.     case J:
  254.     case JAL:
  255.         sprintf(buf,"%-5s %08x",nemonic[op],(int)((addr&0xf0000000)|(code&0x3ffffff)*4));
  256.         break;
  257.     case BEQ:
  258.     case BNE:
  259.         sprintf(buf,"%-5s %s,%s,%08x\t",nemonic[op],rsna,rtna,(int)(addr+(immS+1)*4));
  260.         DUMPREG(rsno,rtno,0)
  261.         break;
  262.     case BLEZ:
  263.     case BGTZ:
  264.         CHECK(rtno) /* err */
  265.         sprintf(buf,"%-5s %s,%08x\t",nemonic[op],rsna,(int)(addr+(immS+1)*4));
  266.         DUMPREG(rsno,0,0)
  267.         break;
  268.     case ADDI:
  269.     case ADDIU:
  270.     case SLTI:
  271.     case SLTIU:
  272.     case ANDI:
  273.     case ORI:
  274.     case XORI:
  275.     case LUI:
  276.         sprintf(buf,"%-5s %s,%s,%d\t# %04x",nemonic[op],rtna,rsna,(int)immS,(int)(code&0xffff));
  277.         DUMPREG(rsno,0,0)
  278.         break;
  279.     case COP0:
  280.         if (rsno&0x10) {
  281.             CHECK(code && MASK(5,20)) /* err */
  282.             sprintf(buf,"%s",cop0[code&31]);
  283.         } else {
  284.             CHECK(code & MASK(0,11)) /* err */
  285.             switch(rsno) {
  286.                 case MFC:
  287.                 case MTC:
  288.                     sprintf(buf,"%s0  %s,%s",cop[rsno],rtna,cop0regname[rdno]);
  289.                     break;
  290.                 case CFC:
  291.                 case CTC:
  292.                     sprintf(buf,"%s0  %s,%s",cop[rsno],rtna,cregname[rdno]);
  293.                     break;
  294.             }
  295.         }
  296.         break;
  297.     case COP2:
  298.         if (rsno&0x10) {
  299.             sprintf(buf,"cop%d  %08x",op&3,(int)(code&0x1ffffff));
  300.         } else {
  301.             CHECK(code & MASK(0,11)) /* err */
  302.             switch(rsno) {
  303.             case MFC:
  304.             case MTC:
  305.                 sprintf(buf,"%s2  %s,%s",cop[rsno],rtna,cop2regname[rdno]);
  306.                 break;
  307.             case CFC:
  308.             case CTC:
  309.                 sprintf(buf,"%s2  %s,%s",cop[rsno],rtna,cop2cregname[rdno]);
  310.                 break;
  311.             }
  312.         }
  313.         break;
  314.     case LB:
  315.     case LH:
  316.     case LWL:
  317.     case LW:
  318.     case LBU:
  319.     case LHU:
  320.     case LWR:
  321.     case SB:
  322.     case SH:
  323.     case SWL:
  324.     case SW:
  325.     case SWR:
  326.         sprintf(buf,"%-5s %s,%d(%s)\t",nemonic[op],rtna,immS,rsna);
  327.         DUMPREG(rsno,0,0)
  328.         break;
  329.     case LWC0:
  330.     case SWC0:
  331.         sprintf(buf,"%-5s %s,%d(%s)",nemonic[op],cop0regname[rtno],(int)immS,rsna);
  332.         break;
  333.     case SWC2:
  334.     case LWC2:
  335.         sprintf(buf,"%-5s %s,%d(%s)",nemonic[op],cop2regname[rtno],(int)immS,rsna);
  336.         break;
  337.     case LWC1:
  338.     case LWC3:
  339.     case SWC1:
  340.     case SWC3:
  341.         sprintf(buf,"%-5s %s,%d(%s)",nemonic[op],cregname[rtno],(int)immS,rsna);
  342.         break;
  343.     default:
  344.         strcpy(buf,"unknown");
  345.         break;
  346.     }
  347. }
  348.  
  349. #ifdef MAKEDIS
  350.  
  351. int main(int argc,char *argv[])
  352. {
  353.     FILE *fp;
  354.     char *buf,*mem;
  355.     UINT32 addr,startaddr,fsize;
  356.     int   i;
  357. //    char inputbuf[256];
  358.  
  359.     EXE_HEADER *head;
  360.     char strbuf[256];
  361.  
  362.     fp = fopen(argv[1],"rb");
  363.     fseek(fp,0,SEEK_END);
  364.     fsize = ftell(fp);
  365.     fseek(fp,0,SEEK_SET);
  366.     buf = malloc(fsize);
  367.     fread(buf,1,fsize,fp);
  368.     fclose(fp);
  369.  
  370.     head = (void*)buf;
  371.     mem = buf;
  372.     if (memcmp(head->id,"PS-X EXE",8)==0) {
  373.         startaddr = head->t_addr;
  374.         mem+=2048;
  375.     } else {
  376.         if (argc > 2) sscanf(argv[2],"%x",(int *)(&startaddr));
  377.                  else startaddr = 0xbfc00000;
  378.     }
  379.  
  380.     mem-=startaddr;
  381.     addr = startaddr;
  382.  
  383.     for (i=0;i<fsize/4;i++)
  384.         {
  385.             UINT32 code = *(UINT32 *)(mem+addr);
  386.             disasm(strbuf,code,addr);
  387.             printf("%08x %08x %s\n",(int)addr,(int)code,strbuf);
  388.             addr+=4;
  389.         }  
  390. /*
  391.    while(1) {
  392.      for(i=0;i<16;i++) {
  393.           u_long code = *(u_long*)(mem+addr);
  394.           disasm(strbuf,code,addr);
  395.           printf("%08x %08x %s\n",addr,code,strbuf);
  396.           addr+=4;
  397.      }
  398.      printf(">");
  399.      gets(inputbuf);
  400.      if (strcmp(inputbuf,"q")==0) break;
  401.     switch(inputbuf[0]){
  402.     case 'a': { char *endp; addr=strtoul(inputbuf+1,&endp,16); }
  403.     }
  404.    }
  405. */
  406.     return 0;
  407. }
  408. #endif